# -*- coding: utf-8 -*-

__author__ = 'bilibili'

import types
import copy
from spot_misc import filter_dict
from spot_misc import filter_dict_level_2
from spot_excel_reader import spot_excel_reader
from spot_config import spot_config
from spot_excel_analyzer_base import spot_excel_analyzer_base

def sorting_key(x):
    return x['Bookings Attainment']

class attainment_statistics:
    # FUNCTION: __init__(self)
    #   the constructor of the class return_data
    def __init__(self):
        self.below_60_detail = []
        self.between_60_and_80_detail = []
        self.between_80_and_90_detail = []
        self.between_90_and_100_detail = []
        self.more_than_100_detail = []

    # FUNCTION: single_operation(self, list/dict, any, string)
    #   the function will add the in_y into in_x according to in_x's type
    # ARGS:
    #   @in_x: the list or dict, the collection of in_y
    #   @in_y: the value that is added to in_x
    #   @in_key: if the in_x is a dict, this is the key
    # EXCEPTION:
    #   if in_x is not a list or a dict
    def single_operation(self, in_x, in_y, in_key=None):
        if type(in_x) == types.ListType:
            in_x.append(in_y)
        elif type(in_x) == types.DictType:
            in_x[in_key] = in_y
        else:
            raise Exception('Not Supported "res" Type')

    # FUNCTION: length_info(self, bool)
    #   build a list or a dict of counting the class variables
    # ARGS:
    #   @is_list: build a list? else a dict
    # RETURN:
    #   list: a list of the count info
    #   dict: a dict of the count info
    def length_info(self, is_list):
        if is_list:
            res = []
        else:
            res = {}
        self.single_operation(res, len(self.more_than_100_detail), 'more_than_100')
        self.single_operation(res, len(self.between_90_and_100_detail), 'between_90_and_100')
        self.single_operation(res, len(self.between_80_and_90_detail), 'between_80_and_90')
        self.single_operation(res, len(self.between_60_and_80_detail), 'between_60_and_80')
        self.single_operation(res, len(self.below_60_detail), 'below_60')
        return res

    # FUNCTION: length_info(self, bool, bool, int)
    #   build a list or a dict of the class variables' details
    # ARGS:
    #   @is_list: build a list? else a dict
    #   @need_sorting: is the result sorted?
    #   @index: -1 represents all, 0-4 represents each item
    # RETURN:
    #   list: a list of the info details
    #   dict: a dict of the info details
    def detail_info(self, is_list, need_sorting = False, index = -1):
        if is_list:
            res = []
        else:
            res = {}
        if need_sorting:
            self.more_than_100_detail.sort(key = sorting_key, reverse = True)
            self.between_90_and_100_detail.sort(key = sorting_key)
            self.between_80_and_90_detail.sort(key = sorting_key)
            self.between_60_and_80_detail.sort(key = sorting_key)
            self.below_60_detail.sort(key = sorting_key)
        if index == -1 or index == 0:
            self.single_operation(res, self.more_than_100_detail, 'more_than_100')
        if index == -1 or index == 1:
            self.single_operation(res, self.between_90_and_100_detail, 'between_90_and_100')
        if index == -1 or index == 2:
            self.single_operation(res, self.between_80_and_90_detail, 'between_80_and_90')
        if index == -1 or index == 3:
            self.single_operation(res, self.between_60_and_80_detail, 'between_60_and_80')
        if index == -1 or index == 4:
            self.single_operation(res, self.below_60_detail, 'below_60')
        return res

    def the_top_ones(self, cnt):
        res = copy.deepcopy(self)
        res.more_than_100_detail.sort(key = sorting_key, reverse = True)
        res.more_than_100_detail = res.more_than_100_detail[0: cnt]
        res.between_90_and_100_detail.sort(key = sorting_key)
        res.between_90_and_100_detail = res.between_90_and_100_detail[0: cnt]
        res.between_80_and_90_detail.sort(key = sorting_key)
        res.between_80_and_90_detail = res.between_80_and_90_detail[0: cnt]
        res.between_60_and_80_detail.sort(key = sorting_key)
        res.between_60_and_80_detail = res.between_60_and_80_detail[0: cnt]
        res.below_60_detail.sort(key = sorting_key)
        res.below_60_detail = res.below_60_detail[0: cnt]
        return res

def test_attainment_statistics():
    att = attainment_statistics()
    print att.length_info(True)
    print att.length_info(False)

if __name__ == '__main__':
    test_attainment_statistics()

class spot_AM_Report_analyzer(spot_excel_analyzer_base):
    # FUNCTION: __init__(self, string)
    #   the constructor of the class spot_AM_Report_analyzer
    # ARGS:
    #   @config_name: json config file name
    def __init__(self, config_name):
        spot_excel_analyzer_base.__init__(self, config_name)
        self.res_array = []

    def fetch_key(self, in_dict):
        return in_dict['Theater']

    def new_value(self, in_dict):
        return []

    def value_operation(self, key, in_dict):
        self.res_dict[key].append(in_dict)
        self.res_array.append(in_dict)

    def post_build_operation(self):
        pass

    # FUNCTION: customized_calculation(self, [persistant_attr, attr_1, attr_2, theater])
    #   customized calculation for the service
    # ARGS:
    #   @list:
    #       persistant_attr: use to filter the dictionary's first keys
    #       attr_1: key_1
    #       attr_2: key_2
    #       theater: theater name
    # RETURN:
    #   attainment_statistics
    def customized_calculation(self, arg_list):
        persistant_attr = arg_list[0]
        attr_1 = arg_list[1]
        attr_2 = arg_list[2]
        theater = arg_list[3]
        res = attainment_statistics()

        keys = ['AM Name', 'Theater', 'Area', 'Region', 'Sales Role Name', 'Role Segment']

        keys_1 = ['Booked & Commit USD(M)', 'Upside', 'Plan']
        keys_2 = ['Booked & Commit USD(M)', 'Upside USD(M)', 'Quarterly Bookings Target USD(M)']

        for it in self.get_level_1_info(theater):
            tmp_str = it[attr_1][attr_2]
            tmp_str = tmp_str[0: len(tmp_str) - 1] # filter the '%'
            attain = float(tmp_str)
            tmp_dict = {}
            tmp_dict = filter_dict(keys, tmp_dict, keys, it)
            tmp_dict = filter_dict_level_2(keys_1, tmp_dict, persistant_attr, keys_2, it)
            tmp_dict['Bookings Attainment'] = attain
            if attain >= 100.0:
                res.more_than_100_detail.append(tmp_dict)
            elif attain >= 90.0:
                res.between_90_and_100_detail.append(tmp_dict)
            elif attain >= 80.0:
                res.between_80_and_90_detail.append(tmp_dict)
            elif attain >= 60.0:
                res.between_60_and_80_detail.append(tmp_dict)
            else:
                res.below_60_detail.append(tmp_dict)
        return res

    # FUNCTION: get_result_array(self, string)
    #   to get the dictionaries from the excel
    # ARGS:
    #   @theater: the theater string that is specified to get the ared info
    # RETURN:
    #   list: the dictionaries list that contains the content from the excel
    def get_level_1_info(self, key_1):
        if key_1 == '':
            return self.res_array
        return self.res_dict[key_1]

def test_spot_AM_Report_analyzer():
    pass
    # analyzer = spot_AM_Report_analyzer('C:\\svn_repo\\SPOT\\trunk\\DashboardDataService\\resources\\AM_Report.config.json')
    # analyzer.build_whole_table()
    # print len(analyzer.get_result_array(''))

if __name__ == '__main__':
    test_spot_AM_Report_analyzer()